/*
Mem.Get("key"); //获取值
Mem.Put("key","值支持对象更新部分","时间"); //更新值 可以只更新时间 时间0不过期 值不存在返回 false
Mem.Set(key,value,"时间");//设置或者新增值 
Mem.Add(key,"默认值1",time);//增加值  支持时间过期
Mem.Cut(key,"默认值1",time);//减少值 支持时间过期
DMem.Del(key);//删除
DMem.Flush(key);// key 为空清理全部  不为空删除包含关键词
*/
var Kuo_Cache_MongoDB = {
    DB:null,
    Link:"mongodb://127.0.0.1:27017",
    Index:{},
    Table:"memcached",//`keval` `atime`
    //配置参数 Mode("Tools").Time()
    Config:(config)=>{

        if(config && config.dbname){
            Kuo_Cache_MongoDB.Table =  config.dbname;
        }
        if(config && config.Server){
            Kuo_Cache_MongoDB.Link =  config.Server;
        }
        Kuo_Cache_MongoDB.DB = require('mongodb').MongoClient;
        return Kuo_Cache_MongoDB;

    },GetTable:async (key)=>{
        var jihe =  "";
        if(!key){
            jihe =  "memcached";
        }
        if(jihe == ""){
            key = ""+key;
            var jihe_ = key.split("/");
            if(jihe_.length > 1){
                jihe = jihe_[0];
            }else{
                jihe = "memcached";
            }
        }
        if(Kuo_Cache_MongoDB.Index[jihe]){
            return jihe;
        }
        /*创建表建立索引 */
        Kuo_Cache_MongoDB.Index[jihe] = 1;

        //return jihe;
        return new Promise((resolve, reject) => {

            Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link,{useUnifiedTopology: true} , function(err, client) {

                if(err){
                    client.close();
                    resolve(jihe);
                    return jihe;
                }
                const db = client.db(Kuo_Cache_MongoDB.Table);
                const collection = db.collection(jihe);
                collection.createIndex({ name: 1 },{unique:true},function(err, results) {
                    client.close();
                    resolve(jihe);
                    return jihe;
                });
            });
        });

    },Get:async (key)=>{
        /*获取数据 */
        if(!key){
            return false;
        }
        var table = await Kuo_Cache_MongoDB.GetTable(key);
        return new Promise((resolve, reject) => {
            Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link ,{useUnifiedTopology: true} , function(err, client) {

                if(err){
                    client.close();
                    resolve(null);
                    return null;
                }
                const db = client.db(Kuo_Cache_MongoDB.Table );
                const collection = db.collection(table);
                collection.find({name:key}).toArray(function(err, result) {
                    client.close();
                    if(err){    
                        resolve(null);
                        return null;
                    }

                    var data = result[0];
                    if(!data){
                        resolve(null);
                        return null;
                    }
                    if(data.atime >0 &&  Mode("Tools").Time() > data.atime){
                        Kuo_Cache_MongoDB.Del(key);
                        resolve(null);
                        return null;
                    }
                    resolve(data['keval']);
                    return data['keval'];
                });
            });
            
        });
        
    
    },Put:async (key,value,time)=>{
        /*更新*/
        if(!key){
            return false;
        }
        if(!time){
            time = 0;
        }
        var zhi =  await Kuo_Cache_MongoDB.Get(key);
        if(value){
            if(zhi && typeof(zhi) == typeof(value)){
                for(var k in value){
                    zhi[k] = value[k];
                }
                value = zhi;
            }
        }else{
            value = zhi;
        }
        return await Kuo_Cache_MongoDB.Set(key,value,time);

    },Set:async (key,value,time)=>{
        /**设置值  */
        if(!key){
            return false;
        }
        if(!time){
            time = 0;
        }
        if(time > 0){
            time += Mode("Tools").Time();
        }
        var table = await Kuo_Cache_MongoDB.GetTable(key);
        return new Promise((resolve, reject) => {
            Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link ,{useUnifiedTopology: true} , function(err, client) {
                if(err){
                    client.close();
                    resolve(false);
                    return false;
                }
                const db = client.db(Kuo_Cache_MongoDB.Table );
                const collection = db.collection(table);
                var whereStr = {name:key};
                var updateStr = {$set:{atime:time,keval:value } };
                collection.updateOne(whereStr, updateStr, function(err_, res_) {
                    if(err_ || !res_ || res_.result.n < 1){
                        collection.insertOne( { name:key, atime:time,keval:value }, function(err, res) {
                            client.close();
                            if(err || !res || res.result.n < 1){
                                resolve(false);
                                return false;

                            }
                            resolve(true);
                            return true;
                        });
                        return true;
                    }
                    client.close();
                    resolve(true);
                    return true;
                });

            });
        });

    },Add:async (key,value,time)=>{
         /* 增加 */
         if(!time){
            time = 0;
        }
        if(!value){
            value = 1;
        }
        var zhi = Number(await Kuo_Cache_MongoDB.Get(key));
        if(!zhi){
            zhi = 0;
        }
        if(isNaN(zhi)){
            zhi = 0;
        }
        zhi = Number(zhi*1);
        zhi += Number(value);
        await Kuo_Cache_MongoDB.Set(key,zhi,time);
        return zhi;

    },Cut:async (key,value,time)=>{
         /* 增加 */
         if(!time){
            time = 0;
        }
        if(!value){
            value = 1;
        }
        var zhi = Number(await Kuo_Cache_MongoDB.Get(key));
        if(!zhi){
            zhi = 0;
        }
        if(isNaN(zhi)){
            zhi = 0;
        }
        zhi = Number(zhi*1);
        zhi -= Number(value);
        await Kuo_Cache_MongoDB.Set(key,zhi,time);
        return zhi;
    },Del:async (key)=>{
        /*删除缓存 */
        if(!key){
            return false;
        }
        var table = await Kuo_Cache_MongoDB.GetTable(key);
        return new Promise((resolve, reject) => {
            Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link ,{useUnifiedTopology: true} , function(err, client) {
                if(err){
                    client.close();
                    resolve(false);
                    return false;
                }
                const db = client.db(Kuo_Cache_MongoDB.Table );
                const collection = db.collection(table);
                var whereStr = {"name":key};
                collection.deleteOne(whereStr, function(err, obj) {
                    client.close();
                    if(err){
                        resolve(false);
                        return false;
                    }
                    resolve(true);
                    return true;
                });
            });
        });
       
    },Total:async ()=>{
        /*统计数据 */
        return new Promise((resolve, reject) => {
            Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link ,{useUnifiedTopology: true} , function(err, client) {
                const db = client.db(Kuo_Cache_MongoDB.Table);
                db.stats(function(e,w){
                    client.close();
                    if(e){
                        resolve(0);
                        return 0;
                    }
                    if(w && w.objects){
                        resolve(w.objects);
                        return w.objects;
                    }
                    resolve(0);
                    return 0;
                });
            });
        });    
       
    },Flush:async (key)=>{
        /*清空数据 */
        if(key){
            var table = await Kuo_Cache_MongoDB.GetTable(key+"/");
            return new Promise((resolve, reject) => {
                Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link ,{useUnifiedTopology: true} , function(err, client) {
                    const db = client.db(Kuo_Cache_MongoDB.Table );
                    const collection = db.collection(table);
                    collection.drop(function(err, delOK) {
                        client.close();
                        if(err){
                            resolve(false);
                            return false;
                        }
                        resolve(true);
                        return true;
                    });
                });
            });

        }else{

            return new Promise((resolve, reject) => {
                Kuo_Cache_MongoDB.DB.connect(Kuo_Cache_MongoDB.Link ,{useUnifiedTopology: true} , function(err, client) {
                    const db = client.db(Kuo_Cache_MongoDB.Table );
                    db.dropDatabase(function(err, delOK) {
                        client.close();
                        if(err){
                            resolve(false);
                            return false;
                        }
                        resolve(true);
                        return true;
                    });
                });
            });
            
        }

        return true;
    },Save:async ()=>{
        /* 预留接口存档 */

        return  true;
    }

};
module.exports = Kuo_Cache_MongoDB;